package com.youxin.chat.user.context;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

public class ImageUtil {
    private static final Logger logger = LoggerFactory.getLogger(ImageUtil.class);

    /**
     * 生成组合头像
     *
     * @param paths 用户头像地址
     * @throws IOException
     */
    public static byte[] getCombinationOfHead(List<String> paths) throws IOException {
        List<BufferedImage> bufferedImages = new ArrayList<>();
        // 压缩图片所有的图片生成尺寸
        int imgWidth = 0;
        int imgHeight = 0;
        if (paths.size() == 1) {
            imgWidth = 180;
            imgHeight = 180;
        } else if (paths.size() >= 2 && paths.size() <= 4) {
            imgWidth = 90;
            imgHeight = 90;
        } else if (paths.size() > 4) {
            imgWidth = 60;
            imgHeight = 60;
        }
        for (int i = 0; i < paths.size(); i++) {
            bufferedImages.add(ImageUtil.resize(paths.get(i), imgHeight, imgWidth, true));
        }

        int width = 180; // 画板的宽高
        int height = 180; // 画板的高度
        // BufferedImage.TYPE_INT_RGB可以自己定义可查看API
        BufferedImage outImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // 生成画布
        Graphics g = outImage.getGraphics();
        Graphics2D g2d = (Graphics2D) g;
        // 设置背景色
        g2d.setBackground(new Color(231, 231, 231));
        // 通过使用当前绘图表面的背景色进行填充来清除指定的矩形。
        g2d.clearRect(0, 0, width, height);
        // 开始拼凑 根据图片的数量判断该生成那种样式的组合头像目前为4中
        for (int i = 1; i <= bufferedImages.size(); i++) {
            if (bufferedImages.size() == 9) {
                if (i <= 3) {
                    g2d.drawImage(bufferedImages.get(i - 1), 60 * (i - 1), 0, null);
                } else if (i > 3 && i <= 6) {
                    g2d.drawImage(bufferedImages.get(i - 1), 60 * (i - 4), 60, null);
                } else {
                    g2d.drawImage(bufferedImages.get(i - 1), 60 * (i - 7), 120, null);
                }
            } else if (bufferedImages.size() == 8) {
                if (i <= 3) {
                    g2d.drawImage(bufferedImages.get(i - 1), 60 * (i - 1), 0, null);
                } else if (i > 3 && i <= 6) {
                    g2d.drawImage(bufferedImages.get(i - 1), 60 * (i - 4), 60, null);
                } else {
                    g2d.drawImage(bufferedImages.get(i - 1), 30 + 60 * (i - 7), 120, null);
                }
            } else if (bufferedImages.size() == 7) {
                if (i <= 3) {
                    g2d.drawImage(bufferedImages.get(i - 1), 60 * (i - 1), 0, null);
                } else if (i > 3 && i <= 6) {
                    g2d.drawImage(bufferedImages.get(i - 1), 60 * (i - 4), 60, null);
                } else {
                    g2d.drawImage(bufferedImages.get(i - 1), 60, 120, null);
                }
            } else if (bufferedImages.size() == 6) {
                if (i <= 3) {
                    g2d.drawImage(bufferedImages.get(i - 1), 60 * (i - 1), 30, null);
                } else {
                    g2d.drawImage(bufferedImages.get(i - 1), 60 * (i - 4), 90, null);
                }
            } else if (bufferedImages.size() == 5) {
                if (i <= 3) {
                    g2d.drawImage(bufferedImages.get(i - 1), 60 * (i - 1), 30, null);
                } else {
                    g2d.drawImage(bufferedImages.get(i - 1), 30 + 60 * (i - 4), 90, null);
                }
            } else if (bufferedImages.size() == 4) {
                if (i <= 2) {
                    g2d.drawImage(bufferedImages.get(i - 1), 90 * (i - 1), 0, null);
                } else {
                    g2d.drawImage(bufferedImages.get(i - 1), 90 * (i - 3), 90, null);
                }
            } else if (bufferedImages.size() == 3) {
                if (i == 3) {
                    g2d.drawImage(bufferedImages.get(i - 1), 45, 90, null);
                } else {
                    g2d.drawImage(bufferedImages.get(i - 1), 90 * (i - 1), 0, null);
                }
            } else if (bufferedImages.size() == 2) {
                g2d.drawImage(bufferedImages.get(i - 1), 90 * (i - 1), 45, null);
            } else if (bufferedImages.size() == 1) {
                g2d.drawImage(bufferedImages.get(i - 1), 0, 0, null);
            }
            // 需要改变颜色的话在这里绘上颜色。可能会用到AlphaComposite类
        }
        String format = "JPG";
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ImageIO.write(outImage, format, out);
        return out.toByteArray();
    }

    /**
     * 图片缩放
     *
     * @param filePath
     * @param height
     * @param width
     * @param bb       比例不对时是否需要补白
     * @return
     */
    public static BufferedImage resize(String urlPath, int height, int width, boolean bb) {
        try {
            double ratio = 0; // 缩放比例
            URL url = new URL(urlPath);
            InputStream inputStream = new DataInputStream(url.openStream());

            BufferedImage bi = ImageIO.read(inputStream);
            Image itemp = bi.getScaledInstance(width, height, Image.SCALE_SMOOTH);
            // 计算比例
            if ((bi.getHeight() > height) || (bi.getWidth() > width)) {
                if (bi.getHeight() > bi.getWidth()) {
                    ratio = (new Integer(height)).doubleValue() / bi.getHeight();
                } else {
                    ratio = (new Integer(width)).doubleValue() / bi.getWidth();
                }
                AffineTransformOp op = new AffineTransformOp(
                        AffineTransform.getScaleInstance(ratio, ratio), null);
                itemp = op.filter(bi, null);
            }
            if (bb) {
                BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
                Graphics2D g = image.createGraphics();
                g.setColor(Color.white);
                g.fillRect(0, 0, width, height);
                if (width == itemp.getWidth(null)) {
                    g.drawImage(itemp, 0, (height - itemp.getHeight(null)) / 2,
                            itemp.getWidth(null), itemp.getHeight(null),
                            Color.white, null);
                } else {
                    g.drawImage(itemp, (width - itemp.getWidth(null)) / 2, 0,
                            itemp.getWidth(null), itemp.getHeight(null),
                            Color.white, null);
                }
                g.dispose();
                itemp = image;
            }
            return (BufferedImage) itemp;
        } catch (IOException e) {
            logger.error("生成合成头像出错", e);
        }
        return null;
    }

    /**
     * byte数组转换成16进制字符串
     *
     * @param src
     * @return
     */
    public static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder();
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

    /**
     * 根据文件流读取图片文件真实类型
     *
     * @param
     * @return jpg、jpeg、png、gif、bmp
     */
    public static String getTypeByStream(InputStream is) {
        byte[] b = new byte[4];
        try {
            is.read(b, 0, b.length);
        } catch (IOException e) {
            e.printStackTrace();
        }
        String type = bytesToHexString(b).toUpperCase();
        if (type.contains("FFD8FF")) {
            return "jpg";
        } else if (type.contains("89504E47")) {
            return "png";
        } else if (type.contains("47494638")) {
            return "gif";
        } else if (type.contains("424D")) {
            return "bmp";
        }
        return type;
    }

    /**
     * @param isPicture
     * @return jpg、jpeg、png、gif、bmp)
     */
    public static boolean isPicture(InputStream is) {
        try {
            String type = getTypeByStream(is);
            if (type.equals("jpg") || type.equals("png") || type.equals("gif") || type.equals("bmp")) {
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }


}
